#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "def.h"

typedef int datatype;


typedef struct flight { char number[10]; //航班号
    char staddress[10]; //起点站
    char arraddress[10]; //终点站
    char date[10]; //班期
    char type; //机型
    int stime; //起飞时间
    int atime; //到达时间
    float price; //票价
    struct list_head my;
}flight,*fllist;


fllist creat_head(){
    fllist head = (fllist)malloc(sizeof(flight));
    if(head == NULL){
        printf("malloc err\n");
        return NULL;
    }
    INIT_LIST_HEAD(&(head->my));
    return head;
}

fllist creat_node(){
    fllist node=creat_head();
    if(node == NULL){
        printf("create head err\n");
        return NULL;
    }
    memset(node,0,sizeof(flight));
    return node;
}

static void list_add(struct list_head* new,struct list_head* head){
    __list_add(new,head,head->next);
}

void insert_head(fllist head){
    fllist new = creat_node();
    if(new == NULL){
        printf("create new err\n");
        return ;
    }

    printf("请输入:航班号: 起点站: 终点站: 班期: 机型: 起飞时间: 到达时间: 票价: (用空格隔开)\n");
    scanf("%s %s %s %s %c %d %d %f",new->number,new->staddress,new->arraddress,new->date,&(new->type),&(new->stime),&(new->atime),&(new->price));

    list_add(&(new->my),&(head->my));
    printf("输入成功\n");
    return;
    
}

void show(const fllist head){
    struct list_head* pos=NULL;
    fllist node = NULL;
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
            printf("链表为空\n");
        }
    list_for_each(pos,&(head->my)){
        node = list_entry(pos,struct flight,my);
        printf("航班号:%s 起点站:%s 终点站:%s 班期:%s 机型:%c 起飞时间:%d 到达时间:%d 票价:%.2f (用空格隔开)\n",
        node->number,node->staddress,node->arraddress,node->date,node->type,node->stime,node->atime,node->price);
    }
    printf("\n");

}

//长度计算
int len(const fllist head){
    if(head == NULL){
        printf("head错误\n");
        return -1;
    }
    if((&(head->my))->next == &(head->my)){
            printf("链表为空\n");
            return -1;
    }
    struct list_head* pos=NULL;
    int len=0;
    list_for_each(pos,&(head->my)){
        len++;
    }
    return len;

}

//节点下标
struct list_head* xiabiao(const fllist head,int i){
    if(head == NULL){
        printf("head错误\n");
        return NULL;
    }
    struct list_head* pos=NULL;
    int len=0;
    if((&(head->my))->next == &(head->my)){
            printf("链表为空\n");
            return NULL;
    }
    list_for_each(pos,&(head->my)){
        len++;
        if(len == i){
            return pos;
        }
    }

}

 //日期查找函数
void find_node_date(const fllist head,const char* find){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
        return;
    }
    printf("日期为%s的有:\n",find);
    fllist pos=NULL;
    int true = -1;
    list_for_each_entry(pos,&(head->my),my){
        if( strcmp(pos->date,find) == 0){
            printf("航班号:%s 起点站:%s 终点站:%s 班期:%s 机型:%c 起飞时间:%d 到达时间:%d 票价:%.2f (用空格隔开)\n",
            pos->number,pos->staddress,pos->arraddress,pos->date,pos->type,pos->stime,pos->atime,pos->price);
            true=1;
        }
    }
    if(true != 1){
        printf("没有找到！\n");
        return;
    }
    return;
}

//起始地点查找函数
void find_node_staddress(const fllist head,const char* find){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
        return;
    }
    printf("起点站位于%s的有:\n",find);

    fllist pos=NULL;
    int true = -1;
    list_for_each_entry(pos,&(head->my),my){
        if( strcmp(pos->staddress,find) == 0){
            printf("航班号:%s 起点站:%s 终点站:%s 班期:%s 机型:%c 起飞时间:%d 到达时间:%d 票价:%.2f (用空格隔开)\n",
            pos->number,pos->staddress,pos->arraddress,pos->date,pos->type,pos->stime,pos->atime,pos->price);
            true=1;
        }
    }
    if(true != 1){
        printf("没有找到！\n");
        return;
    }
    return;
}

//到达地点查找函数
void find_node_arraddress(const fllist head,const char* find){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
        return;
    }
    printf("终点站位于%s的有:\n",find);

    fllist pos=NULL;
    int true = -1;
    list_for_each_entry(pos,&(head->my),my){
        if( strcmp(pos->arraddress,find) == 0){
            printf("航班号:%s 起点站:%s 终点站:%s 班期:%s 机型:%c 起飞时间:%d 到达时间:%d 票价:%.2f (用空格隔开)\n",
            pos->number,pos->staddress,pos->arraddress,pos->date,pos->type,pos->stime,pos->atime,pos->price);
            true=1;
        }
    }
    if(true != 1){
        printf("没有找到！\n");
        return;
    }
    return;
}

//选择查找方式
void find_node_xuanzhe(const fllist head){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
        return;
    }
    int xuanzhe=-1;
    printf("请输入:1,按日期查找   2,按地点查找: ");//选择查找方式
    scanf("%d",&xuanzhe);
    char date[10]="";
    if(xuanzhe == 1){   //日期查找
        printf("请输入日期: ");
        scanf("%s",date);
        find_node_date(head,date);
        return;
    }else if(xuanzhe == 2){ //地点查找
        int xz=-1;
        printf("请选择:1,查询起始地点  2,查询到达地点: ");
        scanf("%d",&xz);
        if(xz == 1){            //起始地点查找
            printf("请输入地点: ");
            scanf("%s",date);
            find_node_staddress(head,date);
        }else if(xz == 2){      //到达地点查找
            printf("请输入地点: ");
            scanf("%s",date);
            find_node_arraddress(head,date);
        }else{
            printf("输入错误!\n");
        }
    }else{
        printf("输入错误!\n");
        return;
    }
    return;
}

//节点交换（不删除）
void swap_nodes(struct list_head *node1, struct list_head *node2)
{

    struct list_head *prev1 = node1->prev;
    struct list_head *next1 = node1->next;
    struct list_head *prev2 = node2->prev;
    struct list_head *next2 = node2->next;

    if (prev1 == node2) {
        // node1 在 node2 后
        __list_del(node1->prev,node1->next);
        __list_del(node2->prev,node2->next);
        list_add_tail(node1, prev2->next);
        list_add_tail(node2, node1->next);
    } else if (next1 == node2) {
        // node1 在 node2 前
        __list_del(node1->prev,node1->next);
        __list_del(node2->prev,node2->next);
        list_add_tail(node2, prev1->next);
        list_add_tail(node1, node2->next);
    } else {
        // node1 node2 不相邻
        __list_del(node1->prev,node1->next);
        __list_del(node2->prev,node2->next);
        list_add_tail(node1, prev2->next);
        list_add_tail(node2, next1->next);
    }
}

//起飞时间排序
void pstime(fllist head){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
            printf("链表为空\n");
            return;
    }
    struct list_head* pos2=NULL;
    struct list_head* pos=NULL;

    fllist node1 = NULL;
    fllist node2 = NULL;

    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
    }
    else{
        for(int i = 1;i <= len(head);i++){
            for(int j= 1;j<=len(head)-1;j++){
                pos=xiabiao(head,j);
                pos2=xiabiao(head,j+1);
                node1 = list_entry(pos,struct flight,my);
                node2 = list_entry(pos2,struct flight,my);
                if(node1->stime > node2->stime){
                    swap_nodes(&(node1->my),&(node2->my));
                }
            }
        }
    }
    return;
}

//起飞地址排序
void pstaddress(fllist head){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    if((&(head->my))->next == &(head->my)){
            printf("链表为空\n");
            return;
    }
    struct list_head* pos2=NULL;
    struct list_head* pos=NULL;

    fllist node1 = NULL;
    fllist node2 = NULL;

    if((&(head->my))->next == &(head->my)){
        printf("链表为空\n");
    }
    else{
        for(int i = 1;i <= len(head);i++){
            for(int j= 1;j<=len(head)-1;j++){
                pos=xiabiao(head,j);
                pos2=xiabiao(head,j+1);
                node1 = list_entry(pos,struct flight,my);
                node2 = list_entry(pos2,struct flight,my);
                if( node1->staddress[0] > (node2->staddress)[0]){
                    swap_nodes(&(node1->my),&(node2->my));
                }
            }
        }
    }
    return;
}

void fenge(void){
    printf("-----------------------------------------------\n");
}

void jiemian(fllist head){
    if(head == NULL){
        printf("head错误\n");
        return;
    }
    int xuanzhe=0,true=1;
    fenge();
    
    while(true){
        printf("请选择1,录入 2,显示所有航班信息 3,查询 4,排序 5,退出: ");
        scanf("%d",&xuanzhe);
        fenge();
        if(xuanzhe == 1){
            int k=1;
            while(k){
                printf("1,录入 2,退出: ");
                scanf("%d",&k);
                if(k == 1){
                    insert_head(head);
                }else if(k == 2){
                    k=0;
                }else{
                    printf("输入错误!\n");
                }
            }
            fenge();
        }else if(xuanzhe == 2){
            show(head);
            fenge();
        }else if(xuanzhe == 3){
            find_node_xuanzhe(head);
            fenge();
        }else if(xuanzhe == 4){
            int k=1;
            while(k){
                printf("1,按起飞时间从小到大 2,按起飞地址 3,退出: ");
                scanf("%d",&k);
                if(k == 1){
                    pstime(head);
                    show(head);
                    fenge();
                }else if(k == 2){
                    pstaddress(head);
                    show(head);
                    fenge();
                }
                else if(k == 3){
                    k=0;
                }else{
                    printf("输入错误!\n");
                }
            }
            fenge();
        }else if(xuanzhe == 5){
            true=0;
        }else{
            printf("输入错误!\n");
        }
    }
}




int main(void){
    fllist head = creat_head();

    jiemian(head);

    return 0;
}